function [idx, maxNChan] = bciChanMapping(bci,chanIdx,mapFrom,mapTo)
% [idx, maxNChan] = bciChanMapping(bci,chanIdx,mapFrom,mapTo)
% resolve channel indexing (always assumes sorted indices)
% four interpretations of channel mapping:
% 'act' - the actual channel indices (as defined in a layout file for topoplots)
% 'buf' - the buffer channel indices as received by the ring buffer
% 'ep'  - the channel indices of a working set (the preprocessed channels) used
%         for creating epochs
% 'good' - the channel indices after deselecting bad channels (used in train
%          data set)
% INPUT: bci - parameter struct
%        chanIdx - indices to transform
%        'mapFrom' - string that defines where the indices come from
%        'mapTo' - string that defines where to transform
% OUTPUT:
%        idx - the indices
%        maxNChan - default number of channels 
% 2011/06/09 CR wrote it


% first map all to actual indices
% begin from smallest subset
if strfind(mapFrom,'good'),
    epChan = bci.goodChan(chanIdx);
else
    epChan = 1:length(bci.preprocChan);
end
if strfind(mapFrom,'ep'),
    bufChan = bci.preprocChan(chanIdx);
else
    bufChan = bci.preprocChan(epChan);
end
if strfind(mapFrom,'buf'),
    [dummy,actualChan] = intersect(bci.init.dataChan,chanIdx);
else
    [dummy,actualChan] = intersect(bci.init.dataChan,bufChan);
end

if strfind(mapFrom,'act'),
    actualChan = chanIdx;
end

% calculate return value
bufChan = bci.init.dataChan(actualChan);
[dummy, epChan] = intersect(bci.preprocChan,bufChan);
if strfind(mapTo,'act'),
    idx = actualChan;
    maxNChan = length(bci.init.dataChan);
elseif strfind(mapTo,'buf'),
    idx = bufChan;
    maxNChan = length(bci.preprocChan);
elseif strfind(mapTo,'ep'),
    idx=epChan;
    maxNChan = length(bci.preprocChan);
elseif strfind(mapTo,'good'),    
    [dummy, idx] = intersect(bci.goodChan,epChan);
    maxNChan = length(bci.goodChan);    
end